//package com.csx.governance.traffic.adapter.outbound;
//
//import cn.hutool.core.collection.CollectionUtil;
//import cn.hutool.core.lang.Assert;
//import com.csx.governance.traffic.adapter.config.TrafficLoadBalancerConfiguration;
//import com.csx.governance.traffic.core.context.TrafficRequest;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
//import org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor;
//import org.springframework.cloud.client.loadbalancer.LoadBalancerRequestFactory;
//import org.springframework.cloud.client.loadbalancer.reactive.LoadBalancedExchangeFilterFunction;
//import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClientSpecification;
//import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
//import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
//import org.springframework.context.support.GenericApplicationContext;
//import org.springframework.http.HttpRequest;
//import org.springframework.http.client.ClientHttpRequestExecution;
//import org.springframework.http.client.ClientHttpResponse;
//
//import java.io.IOException;
//import java.net.URI;
//import java.util.ArrayList;
//import java.util.List;
//import java.util.Map;
//
///**
// * @author cuisongxu
// * @date 2023/4/12 16:29
// */
//public class TrafficReactiveLoadBalancerInterceptor extends LoadBalancerInterceptor {
//
//    private static final Logger logger = LoggerFactory.getLogger(TrafficReactiveLoadBalancerInterceptor.class);
//
//    private final GenericApplicationContext applicationContext;
//
//    private final LoadBalancedExchangeFilterFunction loadBalancedExchangeFilterFunction;
//
//    private LoadBalancerClient loadBalancerClient;
//
//    private final LoadBalancerRequestFactory loadBalancerRequestFactory;
//
//    public TrafficReactiveLoadBalancerInterceptor(GenericApplicationContext applicationContext,
//                                          LoadBalancerClient loadBalancer,
//                                          LoadBalancerRequestFactory requestFactory,
//                                          LoadBalancedExchangeFilterFunction loadBalancedExchangeFilterFunction) {
//        super(loadBalancer, requestFactory);
//        this.applicationContext = applicationContext;
//        this.loadBalancerClient = loadBalancer;
//        this.loadBalancerRequestFactory = requestFactory;
//        this.loadBalancedExchangeFilterFunction = loadBalancedExchangeFilterFunction;
//    }
//
//    @Override
//    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
//        if(!(request instanceof TrafficRequest)) {
//            logger.debug("This request will not join full link grayscale");
//            return super.intercept(request, body, execution);
//        }
//        final URI originUri = request.getURI();
//        String serviceName = originUri.getHost();
//
//        registerOutBoundServiceNameBean(serviceName);
//
//        addConfigurationsToLoadBalancerClientFactory();
//
//        Assert.notNull(serviceName, "Request URL don't contain a valid hostname: " + originUri);
//        loadBalancedExchangeFilterFunction.filter();
//        return loadBalancerClient.execute(serviceName, this.loadBalancerRequestFactory.createRequest(request, body, execution));
//    }
//
//    /**
//     * <p>注册serviceName名称的Bean,类型为 {@link LoadBalancerClientSpecification},主要作用为向LoadBalancer的子容器中注册 {@link TrafficLoadBalancerConfiguration}</p>
//     * <p>该类是一个配置类，配置类中注册了一个后置处理器 {@link LoadBalancerInstanceSupplierBeanPostProcessor},负责包装 LoadBalancer子容器中的 {@link ServiceInstanceListSupplier}类型的Bean</p>
//     * <p>使得所有 {@link ServiceInstanceListSupplier} 中加入全链路灰度自定义的实例过滤逻辑</p
//     */
//    private void registerOutBoundServiceNameBean(String serviceName) {
//        if(!applicationContext.containsBean(serviceName)) {
//            applicationContext.registerBean(serviceName, LoadBalancerClientSpecification.class, () -> new LoadBalancerClientSpecification(serviceName, new Class[]{TrafficLoadBalancerConfiguration.class}));
//        }
//    }
//
//    /**
//     * <p>将容器中所有的 {@link LoadBalancerClientSpecification} 类型的Bean加入到 {@link LoadBalancerClientFactory#setConfigurations(List)}中, 使得在创建LoadBalancer子容器时能够加入
//     * {@link LoadBalancerClientSpecification} 中自定义的配置类(这里是加入负责包装{@link ServiceInstanceListSupplier}的后置处理器,添加全链路灰度的实例过滤逻辑)</p>
//     *
//     */
//    private void addConfigurationsToLoadBalancerClientFactory() {
//        LoadBalancerClientFactory loadBalancerClientFactory = applicationContext.getBean(LoadBalancerClientFactory.class);
//
//        Map<String, LoadBalancerClientSpecification> loadBalancerClientSpecificationMap = applicationContext.getBeansOfType(LoadBalancerClientSpecification.class);
//        List<LoadBalancerClientSpecification> loadBalancerClientSpecificationList = new ArrayList<>();
//        if (CollectionUtil.isNotEmpty(loadBalancerClientSpecificationMap)) {
//            loadBalancerClientSpecificationList = new ArrayList<>(loadBalancerClientSpecificationMap.values());
//        }
//
//        loadBalancerClientFactory.setConfigurations(loadBalancerClientSpecificationList);
//    }
//
//
//}
